package com.tegtech.core.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import com.google.common.collect.Lists;
import com.tegtech.common.constant.Header;
import com.tegtech.common.domain.Result;
import com.tegtech.common.enums.HttpStatus;
import com.tegtech.common.utils.http.RequestUriMatcher;
import com.tegtech.common.utils.http.ServletUtils;

import cn.hutool.core.util.StrUtil;

@Component
public class SignatureFilter extends OncePerRequestFilter {
	
	// 验签过滤开关
	@Value("${sign.enabled}")
	private boolean enabled;
	
	// 无需签名校验的uri，多个用逗号隔开
	@Value("${sign.excludeUris}")
	private String excludeUris;
	
	// 允许匿名访问的uri，多个用逗号隔开
	@Value("${token.excludeUris}")
	private String tokenExcludeUris;

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		// 过滤无需进行签名校验的请求
		String requestUri = request.getRequestURI();
		if(!enabled || RequestUriMatcher.antMatchs(Lists.newArrayList(excludeUris.split(",")), requestUri)) {
			filterChain.doFilter(request, response);
			return;
		}
		// 获取签名参数
		String requestToken = request.getHeader(Header.X_Request_token);
		String requestTime = request.getHeader(Header.X_Request_time);
		String requestId = request.getHeader(Header.X_Request_id);
		String requestSign = request.getHeader(Header.X_Request_sign);
		
		// 非空校验
		if (StrUtil.isBlank(requestTime) || StrUtil.isBlank(requestId) || StrUtil.isBlank(requestSign)) {
			ServletUtils.reponseData(response, Result.err(HttpStatus.NO_HEADER));
			return;
		}
		// 由于未登录的接口没有access_token，需要校验除此之外的url
		if(!RequestUriMatcher.antMatchs(Lists.newArrayList(tokenExcludeUris.split(",")), requestUri) && StrUtil.isBlank(requestToken)) {
			ServletUtils.reponseData(response, Result.err(HttpStatus.NO_HEADER));
			return;
		}
		// 过期时间校验
		if(SignatureHelper.checkRequestTime(requestTime)) {
			ServletUtils.reponseData(response, Result.err(HttpStatus.REQUEST_EXPIRE));
			return;
		}
		// 重复请求校验
		if(SignatureHelper.checkRequestId(requestId)) {
			ServletUtils.reponseData(response, Result.err(HttpStatus.REQUEST_REQEAT));
			return;
		}
		// 签名校验
		String sign = SignatureHelper.createSignature(requestUri, requestToken, requestTime, requestId);
		if(!requestSign.equals(sign)) {
			ServletUtils.reponseData(response, Result.err(HttpStatus.SIGN_INVALID));
			return;
		}
		// 校验通过，缓存requestId
		SignatureHelper.cacheRequestId(requestId);
		filterChain.doFilter(request, response);
	}

}
